package com.jsftoolkit.utils;

import java.io.IOException;

import javax.faces.context.ResponseWriter;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * SAX {@link ContentHandler} implementation that copies all elements to a
 * {@link ResponseWriter}. Intended as a bridge between XML and the JSF
 * response. This may be preferable to writing XML content directly, as the
 * {@link ResponseWriter} will know how to make any necessary adjustments the
 * client needs.
 * 
 * @author noah
 * 
 */
public class ResponseWriterHandler extends DefaultHandler implements
		ContentHandler {

	private final transient ResponseWriter writer;

	private transient boolean escape;

	public ResponseWriterHandler(final ResponseWriter writer) {
		super();
		this.writer = writer;
	}

	/**
	 * 
	 * @param writer
	 * @param escape
	 *            should the body text be escaped? defaults to false
	 */
	public ResponseWriterHandler(final ResponseWriter writer,
			final boolean escape) {
		this(writer);
		this.escape = escape;
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		try {
			writer.startElement(qName, null);
			for (int i = 0; i < attributes.getLength(); i++) {
				writer.writeAttribute(attributes.getQName(i), attributes
						.getValue(i), null);
			}
		} catch (IOException e) {
			throw new SAXException(e);
		}
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		try {
			if (escape) {
				writer.writeText(ch, start, length);
			} else {
				writer.write(ch, start, length);
			}
		} catch (IOException e) {
			throw new SAXException(e);
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		try {
			writer.endElement(qName);
		} catch (IOException e) {
			throw new SAXException(e);
		}
	}

}
